﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.Lib.Interfaces;
using NGinnBPM.Runtime;
/*
using Castle.Windsor;
using Castle.Windsor.Configuration;
using Castle.Core.Configuration;
using Castle.MicroKernel.Registration;
*/
using System.IO;
using NGinnBPM.Lib.Util;
using System.Collections;
using NLog;
using NGinnBPM.MessageBus;
using NGinnBPM.MessageBus.Impl;

namespace NGinnBPM.Runtime
{
    /// <summary>
    /// NGinn host - hosts nginn engine and handles its configuration.
    /// Current list of NGinn configuration options
    /// TODO: get rid of this class
    /// </summary>
    public class NGinnHost : MarshalByRefObject, IDisposable, INGinnHost
    {
        private Logger log = LogManager.GetCurrentClassLogger();
        private IServiceResolver _wc;


        public NGinnHost(IServiceResolver wc)
        {
            _wc = wc;
        }

        public override object InitializeLifetimeService()
        {
            return null;
        }

        private IConfigParameterProvider NGinnConfig
        {
            get { return _wc.GetInstance<IConfigParameterProvider>(); }
        }

        

        /// <summary>
        /// Windsor container where NGinn is hosted
        /// </summary>
        /// <param name="configProvider"></param>
        /// <returns></returns>
        public IServiceResolver GetContainer()
        {
            return _wc;
        }

        

        /// <summary>
        /// Expose NGinn host for remoting
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public NGinnHost RegisterForRemoting(string url)
        {
            if (url == null)
            {
                url = NGinnConfig.GetString("NGinn.Host.RemotingServiceUrl", null);
                if (url == null) throw new NGinnBPM.Lib.Exceptions.NGinnException("Remoting service url not configured. Set the NGinn.Host.RemotingServiceUrl property");
            }
            System.Runtime.Remoting.ObjRef href = System.Runtime.Remoting.RemotingServices.Marshal(this, url, typeof(INGinnHost));
            log.Info("Registered nginn host for remoting as {0}", href.URI);
            return this;
        }

        /// <summary>
        /// Expose nginn host for remoting. Remoting url is set in NGinn.Host.RemotingServiceUrl property
        /// </summary>
        /// <returns></returns>
        public NGinnHost RegisterForRemoting()
        {
            return RegisterForRemoting(null);
        }

        /// <summary>
        /// Start nginn engine
        /// </summary>
        /// <returns></returns>
        private NGinnHost StartNGinn()
        {
            foreach (IStartableService srv in _wc.GetAllInstances<IStartableService>())
            {
                log.Debug("Starting {0}", srv);
                srv.Start();
                
            }
            return this;
        }

        public NGinnHost StopNGinn()
        {
            foreach (IStartableService srv in _wc.GetAllInstances<IStartableService>())
            {
                log.Debug("Stopping {0}", srv);
                srv.Stop();
            }
            return this;
        }

        #region IDisposable Members

        public void Dispose()
        {
            StopNGinn();
            _wc = null;
        }

        #endregion

        #region INGinnHost Members

        public INGEnvironment Environment
        {
            get { return _wc.GetInstance<INGEnvironment>(); }
        }

        public IProcessPackageRepository PackageRepository
        {
            get { return _wc.GetInstance<IProcessPackageRepository>(); }
        }

        /*public object GetService(string name)
        {
            return _wc.Resolve(name);
        }*/

        #endregion

        #region INGinnHost Members


        public INGEngine NGEngine
        {
            get { return _wc.GetInstance<INGEngine>(); }
        }

        public NGinnBPM.MessageBus.IMessageBus MessageBus
        {
            get { return _wc.GetInstance<IMessageBus>(); }
        }

        public IServiceResolver ServiceLocator
        {
            get { return _wc; }
        }

        #endregion

        #region INGinnHost Members


        public void Start()
        {
            StartNGinn();
        }

        public void Stop()
        {
            StopNGinn();
        }

        #endregion
    }
}
